package org.rency.crawler.fetch.handler;

import javax.annotation.Resource;
import org.rency.crawler.common.enums.ReturnCode;
import org.rency.crawler.common.exception.CrawlerException;
import org.rency.crawler.common.exception.CrawlerIllegalException;
import org.rency.crawler.common.exception.MachineStateException;
import org.rency.crawler.domain.FetchResponse;
import org.rency.crawler.domain.state.FetchStatus;
import org.rency.crawler.fetch.helper.FetchCarrier;
import org.rency.crawler.fetch.repository.FetchedQueueRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 描述: ${TODO}<br>
 * 最近修改时间:2017/11/22 11:09<br>
 *
 * @author CaiyuRen
 * @version V1.0
 * @since 2017/11/22 11:09
 */
public abstract class AbstractFetchHandler implements FetchHandler{

  protected final Logger logger = LoggerFactory.getLogger(this.getClass());

  @Resource
  protected FetchedQueueRepository fetchedQueueRepository;

  @Override
  public void handler(FetchCarrier carrier) {
    carrier.setLogPrefix(this.getLogPrefix(carrier));
    logger.info("开始:{}.",carrier.getLogPrefix());
    try{
      this.onHandler(carrier);
    }catch (Throwable e){
      this.exception(carrier,e);
      carrier.getFetchState().setFsStatus(FetchStatus.EXCEPTION);
    }finally {
      logger.info("结束:{}.",carrier.getLogPrefix());
    }
  }

  @Override
  public String getName() {
    return String.format("%s-%s",this.getHandlerName(),this.getClass().getSimpleName());
  }

  private String getLogPrefix(FetchCarrier carrier){
    return String.format("[%s],[%s],[%s]",this.getName(),carrier.getRequest().getFetchNo(),carrier.getRequest().getFetchUri());
  }

  protected void exception(FetchCarrier carrier, Throwable e) {
    logger.error("异常[{}].", carrier.getLogPrefix(), e);
    ReturnCode returnCode = null;
    String returnMessage = null;
    if (e instanceof CrawlerIllegalException) {
      returnCode = ReturnCode.ILLEGAL_VALID;
      returnMessage = ((CrawlerIllegalException) e).getDetailMessage();
    } else if (e instanceof MachineStateException) {
      returnCode = ((MachineStateException) e).getReturnCode();
      returnMessage = ((MachineStateException) e).getDetailMessage();
    } else if (e instanceof CrawlerException) {
      returnCode = ((CrawlerException) e).getReturnCode();
      returnMessage = ((CrawlerException) e).getDetailMessage();
    } else if (e instanceof Exception) {
      returnCode = ReturnCode.FAIL;
      returnMessage = e.getMessage();
    } else {
      returnCode = ReturnCode.FAIL;
      returnMessage = ReturnCode.FAIL.getMsg();
    }
    carrier.setResponse(FetchResponse.fail(returnCode, returnMessage));
  }

  protected abstract String getHandlerName();

  protected abstract void onHandler(FetchCarrier carrier) throws CrawlerException;

}
